home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / WWW / swish.11 / src / swish.c < prev    next >
C/C++ Source or Header  |  1995-03-12  |  13KB  |  461 lines

  1. /*
  2. ** Copyright (C) 1995, Enterprise Integration Technologies Corp.        
  3. ** All Rights Reserved.
  4. ** Kevin Hughes, kevinh@eit.com 
  5. ** 3/11/94
  6. */
  7.  
  8. #define MAIN_FILE
  9. #include "swish.h"
  10.  
  11. int main(argc, argv)
  12.      int argc;
  13.      char **argv;
  14. {
  15.         char c, word[MAXWORDLEN], wordlist[MAXSTRLEN],
  16.         maxhitstr[MAXSTRLEN], structstr[MAXSTRLEN];
  17.     char tmpindex1[MAXFILELEN], tmpindex2[MAXFILELEN],
  18.         index1[MAXSTRLEN], index2[MAXSTRLEN],
  19.         index3[MAXSTRLEN], index4[MAXSTRLEN];
  20.         int i, j, hasindex, hasdir, hasconf, hasverbose, structure,
  21.         totalfiles, stopwords, index, decode, merge;
  22.     long offsetstart, starttime, stoptime, plimit, flimit;
  23.         FILE *fp1, *fp2;
  24.         struct file *filep;
  25.         struct entry *entryp;
  26.     struct swline *conflist, *tmplist;
  27.  
  28.         index = decode = merge = 0;
  29.         hasindex = hasdir = hasconf = hasverbose = 0;
  30.     followsymlinks = stopwords = 0;
  31.         totalwords = stopwords = 0;
  32.         filelist = NULL;
  33.         entrylist = NULL;
  34.     dirlist = indexlist = conflist = tmplist = NULL;
  35.         suffixlist = nocontentslist = replacelist = NULL;
  36.         pathconlist = dirconlist = fileconlist = NULL;
  37.     titconlist = fileislist = NULL;
  38.         maxhits = -1;
  39.         verbose = VERBOSE;
  40.     plimit = PLIMIT;
  41.     flimit = FLIMIT;
  42.     structure = 1;
  43.         wordlist[0] = '\0';
  44.     structstr[0] = '\0';
  45.     indexn[0] = '\0';
  46.     indexd[0] = '\0';
  47.     indexp[0] = '\0';
  48.     indexa[0] = '\0';
  49.  
  50.         if (argc == 1)
  51.                 usage();
  52.         while (--argc > 0) {
  53.                 ++argv;
  54.                 if ((*argv)[0] != '-')
  55.                         usage();
  56.                 c = (*argv)[1];
  57.         if ((*argv)[2] != '\0' && isalpha((*argv)[2]))
  58.             usage();
  59.                 if (c == 'i') {
  60.                         index = 1;
  61.                         while ((argv + 1)[0] != '\0' && *(argv + 1)[0] != '-') {
  62.                 dirlist = (struct swline *)
  63.                 addswline(dirlist, (++argv)[0]);
  64.                                 argc--;
  65.                         }
  66.                 }
  67.                 else if (c == 'w') {
  68.                         while ((argv + 1)[0] != '\0' && *(argv + 1)[0] != '-') {                                strcpy(word, (++argv)[0]);
  69.                                 argc--;
  70.                                 sprintf(wordlist, "%s%s%s", wordlist,
  71.                                 (wordlist[0] == '\0') ? "" : " ", word);
  72.                         }
  73.                 }
  74.                 else if (c == 'f') {
  75.                         while ((argv + 1)[0] != '\0' && *(argv + 1)[0] != '-') {
  76.                 indexlist = (struct swline *)
  77.                 addswline(indexlist, (++argv)[0]);
  78.                                 argc--;
  79.                         }
  80.                 }
  81.                 else if (c == 'c') {
  82.                         index = 1;
  83.                         hasconf = 1;
  84.                         while ((argv + 1)[0] != '\0' && *(argv + 1)[0] != '-') {
  85.                 conflist = (struct swline *)
  86.                 addswline(conflist, (++argv)[0]);
  87.                                 argc--;
  88.                         }
  89.                 }
  90.                 else if (c == 'l') {
  91.             followsymlinks = 1;
  92.             argc--;
  93.         }
  94.                 else if (c == 'm') {
  95.             if ((argv + 1)[0] == '\0')
  96.                 maxhits = -1;
  97.             else {
  98.                 strcpy(maxhitstr, (++argv)[0]);
  99.                 if (lstrstr(maxhitstr, "all"))
  100.                     maxhits = -1;
  101.                 else if (isdigit(maxhitstr[0]))
  102.                                 maxhits = atoi(maxhitstr);
  103.                 else
  104.                     maxhits = -1;
  105.                             argc--;
  106.             }
  107.                 }
  108.                 else if (c == 't') {
  109.             if ((argv + 1)[0] == '\0')
  110.                 progerr("Specify tag fields (HBtheca).");
  111.             else {
  112.                 structure = 0;
  113.                             strcpy(structstr, (++argv)[0]);
  114.                             argc--;
  115.             }
  116.                 }
  117.                 else if (c == 'v') {
  118.             hasverbose = 1;
  119.             if ((argv + 1)[0] == '\0') {
  120.                 verbose = 3;
  121.                 break;
  122.             }
  123.             else if (!isdigit((argv + 1)[0][0]))
  124.                 verbose = 3;
  125.             else
  126.                             verbose = atoi((++argv)[0]);
  127.                         argc--;
  128.                 }
  129.                 else if (c == 'V')
  130.                         printversion();
  131.                 else if (c == 'z' || c == 'h' || c == '?')
  132.                         usage();
  133.                 else if (c == 'M') {
  134.             merge = 1;
  135.                         while ((argv + 1)[0] != '\0' && *(argv + 1)[0] != '-') {
  136.                 indexlist = (struct swline *)
  137.                 addswline(indexlist, (++argv)[0]);
  138.                                 argc--;
  139.                         }
  140.         }
  141.                 else if (c == 'D') {
  142.             decode = 1;
  143.                         while ((argv + 1)[0] != '\0' && *(argv + 1)[0] != '-') {
  144.                 indexlist = (struct swline *)
  145.                 addswline(indexlist, (++argv)[0]);
  146.                                 argc--;
  147.                         }
  148.                 }
  149.                 else
  150.                         usage();
  151.                 if (argc == 0)
  152.                         break;
  153.         }
  154.  
  155.     hasdir = (dirlist == NULL) ? 0 : 1;
  156.     hasindex = (indexlist == NULL) ? 0 : 1;
  157.  
  158.     if (index && merge)
  159.         index = 0;
  160.  
  161.     if (decode) {
  162.  
  163.         if (!hasindex)
  164.             progerr("Specify the index file to decode.");
  165.  
  166.         while (indexlist != NULL) {
  167.  
  168.                     if ((fp1 = fopen(indexlist->line, "r")) == NULL) {
  169.                 sprintf(errorstr,
  170.                 "Couldn't open the index file \"%s\".",
  171.                 indexlist->line);
  172.                 progerr(errorstr);
  173.             }
  174.             if (!isokindexheader(fp1)) {
  175.                 sprintf(errorstr,
  176.                 "\"%s\" has an unknown format.",
  177.                 indexlist->line);
  178.                 progerr(errorstr);
  179.             }
  180.  
  181.                     decompress(fp1);
  182.             putchar('\n');
  183.                     fclose(fp1);
  184.  
  185.             indexlist = indexlist->next;
  186.         }
  187.         exit(0);
  188.  
  189.     }
  190.         else if (index) {
  191.  
  192.                 if (hasconf)
  193.             while (conflist != NULL) {
  194.                             getdefaults(conflist->line, &hasdir, &hasindex,
  195.                 &plimit, &flimit, hasverbose);
  196.                 conflist = conflist->next;
  197.             }
  198.         if (!hasindex)
  199.             indexlist = (struct swline *)
  200.             addswline(indexlist, INDEXFILE);
  201.         if (!hasdir)
  202.             progerr("Specify directories or files to index.");
  203.  
  204.         if (verbose < 0)
  205.             verbose = 0;
  206.         if (verbose > 3)
  207.             verbose = 3;
  208.         if (verbose)
  209.             starttime = getthetime();
  210.  
  211.         while (dirlist != NULL) {
  212.             if (isdirectory(dirlist->line)) {
  213.                 if (verbose >= 2)
  214.                     printf("\nChecking dir \"%s\"...\n",
  215.                     dirlist->line);
  216.                         indexadir(dirlist->line);
  217.             }
  218.             else if (isfile(dirlist->line)) {
  219.                 if (verbose >= 2)
  220.                     printf("\nChecking file \"%s\"...\n",
  221.                     dirlist->line);
  222.                         indexafile(dirlist->line);
  223.             }
  224.             dirlist = dirlist->next;
  225.         }
  226.  
  227.                 if ((fp1 = fopen(indexlist->line, "w")) == NULL) {
  228.             sprintf(errorstr,
  229.             "Couldn't write the index file \"%s\".",
  230.             indexlist->line);
  231.                         progerr(errorstr);
  232.         }
  233.  
  234.         if (verbose > 1)
  235.             putchar('\n');
  236.         if (verbose)
  237.             printf("Removing very common words... ");
  238.  
  239.                 filep = filelist;
  240.         totalfiles = getfilecount(filep);
  241.         entryp = entrylist;
  242.         stopwords = removestops(entryp, totalfiles, plimit, flimit);
  243.  
  244.         if (verbose) {
  245.             if (stopwords)
  246.                 printf("%d word%s removed.\n",
  247.                 stopwords, (stopwords == 1) ? "" : "s");
  248.             else
  249.                         printf("no words removed.\n");
  250.                         printf("Writing main index... ");
  251.         }
  252.  
  253.         printheader(fp1, indexlist->line, totalwords, totalfiles);
  254.  
  255.         offsetstart = ftell(fp1);
  256.                 for (i = 0; i < MAXCHARS; i++)
  257.                         fprintf(fp1, "%016li", offsets[i]);
  258.                 fputc('\n', fp1);
  259.  
  260.                 printindex(entrylist, fp1);
  261.         printstopwords(fp1);
  262.  
  263.         if (verbose) {
  264.             if (totalwords)
  265.                 printf("%d unique word%s indexed.\n",
  266.                 totalwords, (totalwords == 1) ? "" : "s");
  267.             else
  268.                         printf("no unique words indexed.\n");
  269.                         printf("Writing file index... ");
  270.         }
  271.  
  272.                 printfilelist(filelist, fp1);
  273.         printfileoffsets(fp1);
  274.                 fclose(fp1);
  275.  
  276.                 fp2 = fopen(indexlist->line, "r+");
  277.         fseek(fp2, offsetstart, 0);
  278.                 for (i = 0; i < MAXCHARS; i++)
  279.                         fprintf(fp2, "%016li", offsets[i]);
  280.                 fclose(fp2);
  281.  
  282.         if (verbose) {
  283.             if (totalfiles)
  284.                 printf("%d file%s indexed.\n", totalfiles,
  285.                 (totalfiles == 1) ? "" : "s");
  286.             else
  287.                 printf("no files indexed.\n");
  288.  
  289.             stoptime = getthetime();
  290.  
  291.             printrunning(starttime, stoptime);
  292.                     printf("Indexing done!\n");
  293.         }
  294. #ifdef INDEXPERMS
  295.                 chmod(indexlist->line, INDEXPERMS);
  296. #endif
  297.         exit(0);
  298.  
  299.         }
  300.         else if (merge) {
  301.  
  302.         if (indexlist == NULL)
  303.             progerr("Specify index files and an output file.");
  304.                 if (hasconf)
  305.             while (conflist != NULL) {
  306.                             getdefaults(conflist->line, &hasdir, &hasindex,
  307.                 &plimit, &flimit, hasverbose);
  308.                 conflist = conflist->next;
  309.             }
  310.  
  311.         tmplist = indexlist;
  312.         for (i = 0; tmplist != NULL; i++) {
  313.             strcpy(index4, tmplist->line);
  314.             tmplist = tmplist->next;
  315.         }
  316.         j = i - 2;
  317.         if (i < 3)
  318.             progerr("Specify index files and an output file.");
  319.  
  320.         sprintf(tmpindex1, tmpnam(NULL));
  321.         sprintf(tmpindex2, tmpnam(NULL));
  322.  
  323.         i = 1;
  324.         strcpy(index1, indexlist->line);
  325.         indexlist = indexlist->next;
  326.         while (i <= j) {
  327.             strcpy(index2, indexlist->line);
  328.             if (i % 2) {
  329.                 if (i != 1)
  330.                     strcpy(index1, tmpindex2);
  331.                 strcpy(index3, tmpindex1);
  332.             }
  333.             else {
  334.                 strcpy(index1, tmpindex1);
  335.                 strcpy(index3, tmpindex2);
  336.             }
  337.             if (i == j)
  338.                 strcpy(index3, index4);
  339.             readmerge(index1, index2, index3);
  340.             indexlist = indexlist->next;
  341.             i++;
  342.         }
  343. #ifdef INDEXPERMS
  344.                 chmod(index3, INDEXPERMS);
  345. #endif
  346.         if (isfile(tmpindex1))
  347.             remove(tmpindex1);
  348.         if (isfile(tmpindex2))
  349.             remove(tmpindex2);
  350.  
  351.     }
  352.         else {
  353.  
  354.         for (i = 0; structstr[i] != '\0'; i++)
  355.             switch (structstr[i]) {
  356.             case 'H':
  357.                 structure |= IN_HEAD;
  358.                 break;
  359.             case 'B':
  360.                 structure |= IN_BODY;
  361.                 break;
  362.             case 't':
  363.                 structure |= IN_TITLE;
  364.                 break;
  365.             case 'h':
  366.                 structure |= IN_HEADER;
  367.                 break;
  368.             case 'e':
  369.                 structure |= IN_EMPHASIZED;
  370.                 break;
  371.             case 'c':
  372.                 structure |= IN_COMMENTS;
  373.                 break;
  374.             default:
  375.                 structure |= IN_FILE;
  376.                 break;
  377.             }
  378.  
  379.         if (maxhits <= 0)
  380.             maxhits = -1;
  381.         if (!hasindex)
  382.             indexlist = (struct swline *)
  383.             addswline(indexlist, INDEXFILE);
  384.         search(wordlist, indexlist, structure);
  385.  
  386.     }
  387.  
  388.         exit(0);
  389. }
  390.  
  391. /* Gets the current time in seconds since the epoch.
  392. */
  393.  
  394. long getthetime()
  395. {
  396.         long thetime;
  397.         time_t tp;
  398.  
  399.         thetime = (long) time(&tp);
  400.         return thetime;
  401. }
  402.  
  403. /* Prints the running time (the time it took for indexing).
  404. */
  405.  
  406. void printrunning(starttime, stoptime)
  407.      long starttime;
  408.      long stoptime;
  409. {
  410.         int minutes, seconds;
  411.  
  412.         minutes = (stoptime - starttime) / SECSPERMIN;
  413.         seconds = (stoptime - starttime) % SECSPERMIN;
  414.         printf("Running time: ");
  415.         if (minutes)
  416.                 printf("%d minute%s", minutes, (minutes == 1) ? "" : "s");
  417.         if (minutes && seconds)
  418.                 printf(", ");
  419.         if (seconds)
  420.                 printf("%d second%s", seconds, (seconds == 1) ? "" : "s");
  421.         if (!minutes && !seconds)
  422.                 printf("Less than a second");
  423.         printf(".\n");
  424. }
  425.  
  426. /* Prints the SWISH usage.
  427. */
  428.  
  429. void usage()
  430. {
  431.     printf("  usage: swish [-i dir file ... ] [-c file] [-f file] [-l] [-v (num)]\n");
  432.     printf("         swish -w word1 word2 ... [-f file1 file2 ...] [-m num] [-t str]\n");
  433.     printf("         swish -M index1 index2 ... outputfile\n");
  434.     printf("         swish -D file\n");
  435.     printf("         swish -V\n");
  436.     putchar('\n');
  437.         printf("options: defaults are in brackets\n");
  438.         printf("         -i : create an index from the specified files\n");
  439.         printf("         -w : search for words \"word1 word2 ...\"\n");
  440.         printf("         -t : tags to search in - specify as a string\n");
  441.         printf("              \"HBthec\" - in head, body, title, header,\n");
  442.     printf("              emphasized, or comments\n");
  443.         printf("         -f : index file to create or search from [%s]\n", INDEXFILE);
  444.         printf("         -c : configuration file to use for indexing\n");
  445.         printf("         -v : verbosity level (0 to 3) [%d]\n", VERBOSE);
  446.         printf("         -l : follow symbolic links when indexing\n");
  447.         printf("         -m : the maximum number of results to return [%d]\n", MAXHITS);
  448.     printf("         -M : merges index files\n");
  449.     printf("         -D : decodes an index file\n");
  450.         printf("         -V : prints the current version\n\n");
  451.         printf("version: %s\n", VERSION);
  452.         printf("   docs: http://www.eit.com/software/swish/\n");
  453.         exit(1);
  454. }
  455.  
  456. void printversion()
  457. {
  458.         printf("SWISH %s\n", VERSION);
  459.         exit(0);
  460. }
  461.